; panic.asm - Kernel panicker
; Defines void panic(const char *, ...), void trace(void)
;
;  Copyright 2005 Corey Tabaka
;
;  Licensed under the Apache License, Version 2.0 (the "License");
;  you may not use this file except in compliance with the License.
;  You may obtain a copy of the License at
;
;      http://www.apache.org/licenses/LICENSE-2.0
;
;  Unless required by applicable law or agreed to in writing, software
;  distributed under the License is distributed on an "AS IS" BASIS,
;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;  See the License for the specific language governing permissions and
;  limitations under the License.
;

section .text
bits 32

[extern _printf]
[extern __clear]
[extern _cursor]
[extern _window]

[global _panic]
[global _trace]
[global _abort]

; panic never exits so we don't have to worry about stack frames 
_panic:
	push ebp
	mov ebp,esp
	
	cli
	
	; save registers for stack trace
	push gs
	push fs
	push es
	push ds
	push edi
	push esi
	push dword [ebp]	; store original ebp
	push esp
	push ebx
	push edx
	push ecx
	push eax
	mov eax,[ebp + 4]	; store eip
	push eax
	push cs
	push format_panic
	
	; belay the state dump and clear the screen with blue
	push 24
	push 79
	push 0
	push 0
	push 0x17
	push ' '
	call __clear
	
	; set the cursor to none
	mov dword [esp + 4],16
	mov dword [esp],16
	call _cursor
	
	mov dword [esp + 12],24
	mov dword [esp + 8],79
	mov dword [esp + 4],0
	mov dword [esp],0
	call _window
	
	add esp,24			; clear params off stack
	
	; finish the state dump
	call _printf
	
	leave
	
	add esp,4			; get rid of return address to pass our parameters into printf
	call _printf
	
	push stack_trace
	call _printf
	
	mov dword [esp], sys_halt
	call _printf
	
	; disable the processor
.disable:
	cli
	hlt
	pause
	jmp .disable

; general purpose state tracer
_trace:
	push ebp
	mov ebp,esp
	
	; save registers for stack trace
	push gs
	push fs
	push es
	push ds
	push edi
	push esi
	push dword [ebp]			; store original ebp
	push esp
	push ebx
	push edx
	push ecx
	push eax
	mov eax,[ebp + 4]	; store eip
	push eax
	push cs
	push format_trace
	call _printf
	
	leave
	ret

_abort:
	push ebp
	mov ebp,esp
	
	cli
	
	; save registers for stack trace
	push gs
	push fs
	push es
	push ds
	push edi
	push esi
	push dword [ebp]			; store original ebp
	push esp
	push ebx
	push edx
	push ecx
	push eax
	mov eax,[ebp + 4]	; store eip
	push eax
	push cs
	push format_trace
	call _printf
	
	leave
	
	add esp,4			; get rid of return address to pass our parameters into printf
	call _printf
	
	push stack_trace
	call _printf

.loop:	
	hlt
	jmp .loop

section .data
bits 32
	
format_panic:
	db "Kernel panic!"
format_trace:
	db 0x0a
	db " CS:     %04x EIP: %08x",0x0a,0x0a
	db "EAX: %08x ECX: %08x EDX: %08x EBX: %08x",0x0a
	db "ESP: %08x EBP: %08x ESI: %08x EDI: %08x",0x0a,0x0a
	db " DS:     %04x  ES:     %04x  FS:     %04x  GS:     %04x",0x0a,0x0a
	db 0
stack_trace:
	db 0x0a,0x0a
	db "Stack trace:", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db "    %08x %08x %08x %08x %08x %08x %08x %08x", 0x0a
	db 0
sys_halt:
	db 0x0a,0x0a,"System halted.",0
